﻿using AutoMapper;
using KayakMes.Check.Application.Input;
using KayakMes.Check.Application.OUT;
using KayakMes.Check.Domain;
using KayakMes.Common;
using KayakMes.Common.Dtos.CheckDto;
using KayakMes.Common.Result;
using OracleInternal.SqlAndPlsqlParser.LocalParsing;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace KayakMes.Check.Application.CheckStandard
{
    public class CheckStandard : ICheckStandard
    {
        private readonly BaseReposiotry<CheckStandardModel> baseReposiotry;
        private readonly IMapper mapper;
        private readonly ISqlSugarClient _db;
        private readonly BaseReposiotry<CheckStandardItemModel> baseItemModel;
        private static readonly object _codeLock = new object();

        public CheckStandard(BaseReposiotry<CheckStandardModel> baseReposiotry, IMapper mapper, BaseReposiotry<CheckStandardItemModel> baseItemModel, ISqlSugarClient db)
        {
            this.baseReposiotry = baseReposiotry;
            this.mapper = mapper;
            this.baseItemModel = baseItemModel;
            _db = db;
        }
        /// <summary>
        /// 添加检测标准
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ApiResult<int> AddCheckStandard(AddCheckStandardInput input)
        {
            // 1. 映射主表
            var model = mapper.Map<CheckStandardModel>(input);
            model.Id = YitIdHelper.NextId();
            model.CheckCode = GetCheckItemCode();
            model.CreateTime = DateTime.Now;

            // 2. 映射明细表
            var itemList = new List<CheckStandardItemModel>();
            if (input.ListModel != null && input.ListModel.Count > 0)
            {
                foreach (var item in input.ListModel)
                {
                    var detail = mapper.Map<CheckStandardItemModel>(item);
                    detail.Id = YitIdHelper.NextId();
                    detail.CheckSheetId = model.CheckCode; // 外键关联主表Id
                    itemList.Add(detail);
                }
            }
            var result=0;

            // 3. 事务保存主表和明细表
            _db.Ado.BeginTran();
            try
            {
                result = baseReposiotry.Add(model); // 插入主表
                if (itemList.Count > 0)
                {
                    _db.Insertable(itemList).ExecuteCommand(); // 批量插入明细
                }
                _db.Ado.CommitTran();
            }
            catch (Exception ex)
            {
                _db.Ado.RollbackTran();
                return new ApiResult<int>
                {
                    Code = ApiEnums.Fail,
                    Message = "添加检查标准失败：" + ex.Message,
                    Data = 0
                };
            }

            return new ApiResult<int>
            {
                Code = ApiEnums.Success,
                Message = "添加检查标准成功",
                Data = result
            };
        }
        /// <summary>
        /// 删除检查标准
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ApiResult<int> DeleteCheckStandard(long id)
        {
            // 1. 查询主表
            var model = baseReposiotry.GetModel(id);
            if (model == null)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnums.Fail,
                    Message = "检查标准不存在",
                    Data = 0
                };
            }
            _db.Ado.BeginTran();
            try
            {
                // 2. 删除明细表（CheckSheetId == 主表CheckCode）
               
                var detailList = baseItemModel.GetAll().Where(x => x.CheckSheetId == model.CheckCode).ToList();
                if (detailList.Count > 0)
                {
                    
                    foreach (var item in detailList)
                    {
                        baseItemModel.Delete(item);
                    }
                    // 如果没有DeleteRange方法，可以用：
                    // foreach (var item in detailList) { itemRepo.Delete(item); }
                }

                // 3. 删除主表
                var result = baseReposiotry.Delete(model);

                _db.Ado.CommitTran();

                if (result > 0)
                {
                    return new ApiResult<int>
                    {
                        Code = ApiEnums.Success,
                        Message = "删除检查标准及明细成功",
                        Data = result
                    };
                }
                else
                {
                    return new ApiResult<int>
                    {
                        Code = ApiEnums.Fail,
                        Message = "删除检查标准失败",
                        Data = 0
                    };
                }
            }
            catch (Exception ex)
            {
                _db.Ado.RollbackTran();
                return new ApiResult<int>
                {
                    Code = ApiEnums.Fail,
                    Message = "删除失败：" + ex.Message,
                    Data = 0
                };
            }
        }
        /// <summary>
        /// 获取所有检查标准分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ApiPaging<CheckStandardDto> GetAllCheckStandard(GetCheckStandardInput input)
        {
            var model=baseReposiotry.GetAll().Where(x=>x.IsDeleted==false);
            if(!string.IsNullOrEmpty(input.CheckCode))
            {
                model=model.Where(x=>x.CheckCode==input.CheckCode);
            }
            if(!string.IsNullOrEmpty(input.ProcessName))
            {
                model=model.Where(x=>x.GProcessName==input.ProcessName);
            }
            CheckStandardDto dto=new CheckStandardDto();
            int count=model.Count();
            var list=model.OrderBy(x=>x.Id).Skip((input.PageIndex-1)*input.PageSize).Take(input.PageSize).ToList();
            return new ApiPaging<CheckStandardDto>()
            {
                Total=count,
                PageIndex=input.PageIndex,
                PageSize=input.PageSize,
                Items=mapper.Map<List<CheckStandardDto>>(list)
            };
        }
        /// <summary>
        /// 获取所有单一标准
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ApiResult<CheckStandardDetailResult> GetModelCheckStandard(long id)
        {
            // 1. 查询主表
            var main = baseReposiotry.GetModel(id);
            if (main == null)
            {
                return new ApiResult<CheckStandardDetailResult>
                {
                    Code = ApiEnums.Fail,
                    Data = null,
                    Message = "查询失败，未找到主表数据"
                };
            }

            // 2. 查询明细表（通过CheckCode关联）
            
            var items = baseItemModel.GetAll().Where(x => x.CheckSheetId == main.CheckCode).ToList();

            // 3. 返回主表和明细表数据
            return new ApiResult<CheckStandardDetailResult>
            {
                Code = ApiEnums.Success,
                Message = "查询成功",
                Data = new CheckStandardDetailResult
                {
                    Main = main,
                    Items = items
                }
            };
        }
        /// <summary>
        /// 修改检测标准
        /// </summary>
        /// <param name="checkStandard"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ApiResult<int> UpdateCheckStandard(UpdateCheckStandardInput checkStandard)
        {
           
            _db.Ado.BeginTran();
            try
            {
                // 1. 更新主表
                var model = baseReposiotry.GetModel(checkStandard.Id);
                if (model == null)
                    throw new Exception("主表数据不存在");

                mapper.Map(checkStandard, model);
                var result = baseReposiotry.Update(model);

                // 2. 删除原有明细
                
                var oldItems = baseItemModel.GetAll().Where(x => x.CheckSheetId == model.CheckCode).ToList();
                if (oldItems.Count > 0)
                {
                   
                    foreach (var item in oldItems)
                    {
                        baseItemModel.Delete(item);
                    }
                    // 如果没有DeleteRange方法，可以循环 itemRepo.Delete(item)
                }

                // 3. 插入新明细
                var newItems = new List<CheckStandardItemModel>();
                if (checkStandard.ListModel != null && checkStandard.ListModel.Count > 0)
                {
                    foreach (var item in checkStandard.ListModel)
                    {
                        var entity = mapper.Map<CheckStandardItemModel>(item);
                        entity.Id = YitIdHelper.NextId();
                        entity.CheckSheetId = model.CheckCode;
                        newItems.Add(entity);
                    }
                    _db.Insertable(newItems).ExecuteCommand();
                }

                _db.Ado.CommitTran();
                return new ApiResult<int>
                {
                    Code = ApiEnums.Success,
                    Message = "修改成功",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                _db.Ado.RollbackTran();
                return new ApiResult<int>
                {
                    Code = ApiEnums.Fail,
                    Message = "修改失败：" + ex.Message,
                    Data = 0
                };
            }
        }
        /// <summary>
        /// 随机生成检测项目编号
        /// </summary>
        /// <returns>格式为 PC001 的字符串</returns>
        public string GetCheckItemCode()
        {
            lock (_codeLock)
            {
                var maxCode = baseReposiotry.GetAll()
                    .Where(x => !string.IsNullOrEmpty(x.CheckCode) && x.CheckCode.StartsWith("PC"))
                    .OrderByDescending(x => x.CheckCode)
                    .Select(x => x.CheckCode)
                    .First();

                int nextNumber = 1;

                if (!string.IsNullOrWhiteSpace(maxCode))
                {
                    var numPart = maxCode.Substring(2);
                    if (int.TryParse(numPart, out int currentNum))
                    {
                        nextNumber = currentNum + 1;
                    }
                }

                return $"PC{nextNumber:D3}";
            }
        }
        /// <summary>
        /// 获取所有检测项目
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ApiPaging<ProcessCheckDto> GetAllCheck(GetCheckInput input)
        {
            var query = _db.Queryable<CheckStandardModel, CheckStandardItemModel>((std, item) => 
                    std.CheckCode == item.CheckSheetId)
                .Select((std, item) => new ProcessCheckDto
                {
                    CheckCode = std.CheckCode,
                    CheckName = std.CheckName,
                    CheckWay = std.CheckWay,
                    ProductCategory = std.ProductCategory,
                    CheckVersion = std.CheckVersion,
                    GProcessId = std.GProcessId,
                    GProcessName = std.GProcessName,
                    IsEnabled = std.IsEnabled,
                    SampleCount = std.SampleCount,
                    ItemName = item.ItemName,
                    ItemStandard = item.ItemStandard,
                    ItemTool = item.ItemTool,
                    ItemDescription = item.ItemDescription,
                    CheckSheetId = item.CheckSheetId
                });

            // 可选：条件筛选
            if (!string.IsNullOrEmpty(input.CheckCode))
                query = query.Where(std => std.CheckCode.Contains( input.CheckCode));

            if (!string.IsNullOrEmpty(input.ProcessName))
                query = query.Where(std => std.CheckName.Contains( input.ProcessName));

            // 分页
            var total = 0;
            var items = query.ToPageList(input.PageIndex, input.PageSize, ref total);

            return new ApiPaging<ProcessCheckDto>
            {
                Code = ApiEnums.Success,
                Message = "查询成功",
                Items = items,
                Total = total,
                PageIndex = input.PageIndex,
                PageSize = input.PageSize
            };
        }
        /// <summary>
        /// 检验完毕修改状态
        /// </summary>
        /// <param name="checkCode"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ApiResult<int> UpdateIselete(string checkCode)
        {
            var model=baseReposiotry.GetAll().Where(x=>x.CheckCode==checkCode).First();
            if (model==null)
            {
                return new ApiResult<int>
                {
                    Code = ApiEnums.Fail,
                    Message = "修改失败",
                    Data = 0
                };
            }
            model.IsEnabled = true;
            return new ApiResult<int>
            {
                Code = ApiEnums.Success,
                Message = "修改成功",
                Data = baseReposiotry.Update(model)
            };
        }
        
    }

   
}
